#pragma once
#include <iostream>
#include <cstdlib>
#include <string>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include "InetAddr.hpp"
#include "Comm.hpp"
#include "Socket.hpp"
#include "Logger.hpp"
#include "Protocol.hpp"


class TcpClient
{
    public:
    TcpClient(const std::string& ip,uint16_t port):_tcp(std::make_unique<TcpSocket>()),_addr(port,ip)
    {
        // std::cout << "TcpClient" << std::endl;
        _tcp->BuildClientSocketMethod();
    }

    void Start()
    {
        //不考虑断线重连的情况,连接建立一次后，即可稳定通信
        //while

        // std::cout << "Tcp Start" << std::endl;
        if(!_tcp->Connect(_addr))
        {
            LOG(LogLevel::FATAL) << "client connect error";
            exit(CONNECT_ERR);
        }

        LOG(LogLevel::INFO) << "client connect success";

        //长连接
        while(true)
        {
            int x,y;char oper;
            std::cout << "Please enter X:";
            std::cin >> x;
            std::cout << "Please enter Y:";
            std::cin >> y;
            std::cout << "Please enter Oper:";
            std::cin >> oper;


            Request req(x,y,oper);
            std::string send_str;
            req.Serialize(&send_str);
            Package::Pack(send_str);
            _tcp->Send(send_str);
            // std::cout << send_str << std::endl;
            
            std::string buffer,out;
            do _tcp->Recv(&buffer);while(!Package::Unpack(buffer,&out));
            Response res;
            res.DeSerialize(out);
            res.Print();
        }
    }
    

    
    private:
    std::unique_ptr<Socket> _tcp;//多态机制
    InetAddr _addr;
};